﻿//*** Guidance generated code ***//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using ProjectBase.Core;

using $prjsn$.Common;

namespace $safeprojectname$
{
    public class ComponentArrayValueProvider<TEntity, TID> : EntityArrayValueProvider<TEntity, TID> 
        where TEntity : class, IPersistentObjectWithTypedId<TID>, new()
    {
        #region Write
        public override void SetValue(object target, object value)
        {
            var jArray = value as JArray;

            var shouldBind = jArray.Is()
                             && PropertyInfo.PropertyType.IsGenericType
                             && PropertyInfo.PropertyType.HasType<IEnumerable>();

            if (!shouldBind)
            {
                return;
            }

            var list = PropertyInfo.GetValue(target, null) as IList<TEntity>;
            var array = new List<JObject>(jArray.Cast<JObject>().ToList());

            // the MetaData Attribute for current property
            var attribute = Attributes
                .FirstOrDefault(a => a.Name.IsEqual(PropertyInfo.Name));

            var canEdit = attribute.Is()
                          && attribute.CanEdit;

            if (!canEdit)
            {
                return;
            }

            BindComponent(array, list, attribute);
        }

        protected virtual void BindComponent(IList<JObject> array, IList<TEntity> list, MDAttribute attribute)
        {
            int counter;

            for (counter = 0; counter < list.Count; counter++)
            {
                if (array.Count <= counter)
                {
                    break;
                }
                var jItem = array[counter];
                

                var persistent = new TEntity();
                var reader = jItem.CreateReader();

                var serializer = CreateJsonSerializer(attribute.Attributes, NullValueHandling.Include, persistent);

                serializer.Deserialize<TEntity>(reader);

                list[counter] = persistent;
            }

            // remove remaining
            var listCount = list.Count;
            for (var position = counter; position < listCount; position++ )
            {
                list.RemoveAt(position);
            }

            // append new
            if (array.Count >= counter)
            {
                for (var newPosition = counter; newPosition < array.Count; newPosition++)
                {
                    var jItem = array[newPosition];
                    
                    var persistent = new TEntity();
                    var reader = jItem.CreateReader();

                    var serializer = CreateJsonSerializer(attribute.Attributes, NullValueHandling.Include, persistent);

                    serializer.Deserialize<TEntity>(reader);

                    list.Add(persistent);
                }
            }
        }
        #endregion Write
    }
}